我們首先要瞭解 受控組件 和 非受控組件。這兩者都可以達到所需效果,但它們在實現方式和適合的使用場景上有所差異。
概念: 非受控組件的值不由React的state來控制,而是由原生組件直接控制。我們可以使用 ref 來獲取或設置這個值。
優勢: 主要由原生控制,JS沒有參與太多,性能上有優勢。
劣勢: 當我們需要在更新值時加入一些特定的邏輯,如格式化或檢查,由於不受React的state控制,可能會比較難維護。
運作原理簡介:
JS層:
原生層:
範例:
import React, { useRef } from 'react';
import { View, TextInput, Button, Alert } from 'react-native';
function UncontrolledInput() {
// 使用ref來直接引用TextInput組件
const inputRef = useRef(null);
const handleShowValue = () => {
// 使用ref直接存取TextInput的值
if (inputRef.current) {
Alert.alert("Current Value", inputRef.current.value || '');
}
};
return (
<View style={{ padding: 10 }}>
<TextInput
ref={inputRef} // 設置ref
style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
/>
<Button title="Show Value" onPress={handleShowValue} />
</View>
);
}
概念: 受控組件的值由React的state來控制。每當值有所變化時,都會通過state進行更新。
優勢: 因為都在React上處理,用setState更新值,處理值的邏輯方便
劣勢: 性能上略遜於非受控組件,因為每次輸入都涉及到JS和React的處理。
運作原理簡介:
JS層:
原生層:
範例:
import React, { useState } from 'react';
import { View, TextInput } from 'react-native';
function ControlledInput() {
// 使用state來保存當前的輸入值
const [value, setValue] = useState('');
return (
<View style={{ padding: 10 }}>
<TextInput
style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
value={value} // 當前的輸入值是由state控制的
onChangeText={text => setValue(text)} // 當輸入變化時,更新state的值
/>
</View>
);
}
以性能的角度看,非受控看起來很香,但除非是簡單的場景,不然一般建議還是使用受控組件。非受控組件因為不在React 中處理 state,維護上可能會造成程式碼邏輯不好釐清,尤其程式碼越來越複雜時,會越明顯。
自動對焦對於使用者體驗有不小的提升。例如,當一個頁面載入時,讓特定的輸入框自動獲得焦點,可以簡化使用者操作步驟:
單個輸入框: 使用方法很簡單,將autoFocus設為true即可
<TextInput autoFocus/>
多個輸入框: 友善的做法是自動將焦點從一個輸入框移至下一個。這樣當使用者完成一個輸入框的輸入後,可以直接跳到下一個,無需手動點擊:
function SequentialFocusTextInputs() {
const firstInputRef = React.useRef<TextInput>(null);
const secondInputRef = React.useRef<TextInput>(null);
const thirdInputRef = React.useRef<TextInput>(null);
return (
<>
<TextInput ref={firstInputRef} onSubmitEditing={() => secondInputRef.current?.focus()} /> // 姓名
<TextInput ref={secondInputRef} onSubmitEditing={() => thirdInputRef.current?.focus()} /> // 電話
<TextInput ref={thirdInputRef} /> // 地址
</>
);
}
在上述例子中,我們為每個輸入框設定了一個ref。然後利用onSubmitEditing事件,在使用者按下鍵盤的完成鍵後,自動將焦點轉移到下一個輸入框。
onSubmitEditing屬性:在TextInput組件中,onSubmitEditing是一個回調,它會在使用者按下鍵盤的完成或提交鍵時觸發。讓我們可以執行特定的操作,如將焦點轉移到下一個輸入框。
我可以根據不同情境優化使用不同的鍵盤。
鍵盤類型
keyboardType屬性允許我們為輸入框設定不同的鍵盤類型,如數字、電子郵件地址等,以提供更具情境的輸入體驗:
default: 標準鍵盤。
numeric: 數字鍵盤。
email-address: 為輸入電子郵件設計的鍵盤。
phone-pad: 電話號碼鍵盤。
範例:
<TextInput keyboardType="email-address" />
提示鍵設定
使用returnKeyType屬性來控制鍵盤上的提示鍵文案:
default: 預設,通常顯示為return。
done: 顯示為“done”,適合用在最後一個輸入框。
go: 顯示為go”,適用於網址輸入框或跳轉操作。
next: 顯示為“next”,適合用於切換到下一個輸入框。
search: 顯示文案為“search”,用於搜索欄位。
send: 顯示文案為“send”,尤其適合於聊天界面。
<TextInput style={styles.input} returnKeyType="send" />
今天介紹了TextInput,有些細節看似微不足道,但它們其實都默默的影響了用戶對APP的整體感受。除了上述的使用者技巧外,還要留意的是 iOS 和 Android 的<TextInput />
樣式並不一致,因為它們依賴於各自平台的原生Input組件渲染。所以如希望在兩平台上達到一致的輸入框外觀,記得要做樣式調整。